/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package main;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.PrintWriter;
import java.io.StringWriter;

/**
 *
 * @author Fabien Muguet
 */
public class Outils {


    /**
     * Effectue une homothétie de l'image.
     *
     * @param bi L'image.
     * @param scaleValue La valeur de l'homothétie.
     * @return Une image réduite ou agrandie.
     *
     */
    public static BufferedImage homothetie(BufferedImage bi, double scaleValue) {

        AffineTransform tx = new AffineTransform();
        tx.scale(scaleValue, scaleValue);
        AffineTransformOp op = new AffineTransformOp(tx,
        AffineTransformOp.TYPE_BILINEAR);
        BufferedImage biNew = new BufferedImage(
                (int) (bi.getWidth() * scaleValue),
                (int) (bi.getHeight() * scaleValue),
                bi.getType()
        );
        return op.filter(bi, biNew);
    }

    
    /**
     * Retourne une image qui entre dans le cadre déterminé.
     *
     * @param bi L'image
     * @param dim Dimensions du cadre maximum.
     * @return Une image réduite ou agrandie.
     */
    public static BufferedImage ajuster(BufferedImage bi, Dimension cadre) {

        double echelle = 1.0;

        double width = bi.getWidth();
        double height = bi.getHeight();

        double deltaWidth = width - cadre.width;
        double deltaHeight = height - cadre.height;

        if(deltaWidth > 0) {
            if(deltaHeight > deltaWidth) {
                echelle = cadre.height / height;
            } else {
                echelle = cadre.width / width;
            }

        } else if(deltaHeight > 0) {
            echelle = cadre.height / height;
        } else if ( (cadre.width / width) < (cadre.height / height) ){
            echelle = cadre.width / width;
        } else {
            echelle = cadre.height / height;
        }


        return homothetie(bi, echelle);
    }

     /**
     * Retourne une image etirée qui entre dans le cadre déterminé.
     *
     * @param bi L'image
     * @param dim Dimensions du cadre maximum.
     * @return Une image étirer.
     */
    public static BufferedImage etirer(BufferedImage bi, Dimension cadre) {

        // A MODIFIER
        double echelle = 1.0;

        double width = bi.getWidth();
        double height = bi.getHeight();

        double deltaWidth = width - cadre.width;
        double deltaHeight = height - cadre.height;

        if(deltaWidth > 0) {
            if(deltaHeight > deltaWidth) {
                echelle = cadre.height / height;
            } else {
                echelle = cadre.width / width;
            }

        } else if(deltaHeight > 0) {
            echelle = cadre.height / height;
        } else if ( (cadre.width / width) < (cadre.height / height) ){
            echelle = cadre.width / width;
        } else {
            echelle = cadre.height / height;
        }


        return homothetie(bi, echelle);
    }



    /**
     * Retourne la roation d'une image d'un angle de pAngle degré.
     *
     * @param cImage L'image à rotationner
     * @param pAngle L'angle de rotation en degré
     * @return L'image retournée
     */
    public static BufferedImage rotate(BufferedImage cImage, int pAngle) {
        int lLargeur = cImage.getWidth();
        int lHauteur = cImage.getHeight();
        BufferedImage lImage = new BufferedImage(lLargeur, lHauteur, cImage.getType());
        Graphics2D lObjetGraphique = lImage.createGraphics();

        lObjetGraphique.rotate(Math.toRadians(pAngle), lLargeur/2, lHauteur/2);
        lObjetGraphique.drawImage(cImage, null, 0, 0);
        return lImage;
    }


    /**
     * Applique un effet sepia sur une image
     * @param imgSource
     * @param sepiaIntensity
     * @throws Exception
     */
    public static BufferedImage appliquerSepia(BufferedImage img, int sepiaIntensity) throws Exception {

    int lLargeur = img.getWidth();
    int lHauteur = img.getHeight();

    BufferedImage dest = img;
    WritableRaster rasterDest = dest.getRaster();


    int sepiaDepth = 20;
    int w = img.getWidth();
    int h = img.getHeight();

    WritableRaster raster = img.getRaster();
    int[] pixels = new int[w*h*3];
    raster.getPixels(0, 0, w, h, pixels);

    for (int i=0;i<pixels.length; i+=3)
    {
            int r = pixels[i];
            int g = pixels[i+1];
            int b = pixels[i+2];

            int gry = (r + g + b) / 3;
            r = g = b = gry;
            r = r + (sepiaDepth * 2);
            g = g + sepiaDepth;

            if (r>255) r=255;
            if (g>255) g=255;
            if (b>255) b=255;

            b-= sepiaIntensity;

            if (b<0) b=0;
            if (b>255) b=255;

            pixels[i] = r;
            pixels[i+1]= g;
            pixels[i+2] = b;
    }
    rasterDest.setPixels(0, 0, w, h, pixels);

    return dest;
    }
    


    /**
     * Récupère l'extension du fichier passé en paramêtre.
     * @param nomFichier
     * @return L'extension du fichier.
     */
    public static String recupereExtensionFichier(String nomFichier){
        String extension = null;
        String[] temp =null;
        if(nomFichier.toCharArray()[0] != '.'){
            temp = nomFichier.split("\\.");
            extension = temp[temp.length-1].toLowerCase();
        }
        return extension;
    }

    /**
     * Retourne la pile sous forme de chaine de caractères.
     * @param Exception
     * @return Pile
     */
    public static String getStackTrace(Exception ex){
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }

    /**
     * Retourne le nom du système d'exploitation du dossier.
     * @return
     */
    public static String getSystemName(){
        return (String)System.getProperty("os.name");
    }

}
